//==============================================================================
//
//         DShort - the short (2 bytes) number class in the ofc-library
//
//               Copyright (C) 2003  Dick van Oudheusden
//  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2005-02-05 06:25:38 $ $Revision: 1.12 $
//
//==============================================================================

#include "ofc/DShort.h"
#include <limits.h>
#include <stdlib.h>


#if _INTERFACE_

#include "ofc/config.h"

#include "ofc/DComparable.h"
#include "ofc/DTextable.h"
#include "ofc/DDatable.h"
#include "ofc/DParsable.h"

#include "ofc/DText.h"
#include "ofc/DData.h"

// The Short class implements a number of methods for storing and manipulating short numbers.

@interface DShort : Object <DComparable,DTextable,DDatable,DParsable>
{
@private
  short        _sh;
}

#endif



@implementation DShort


//// Constructors

//
// Initialise to zero number
//
// @return the object
//

- (DShort *) init
{
  [super init];

  _sh = 0;
  
  return self;
}

//
// Initialise to a number
//
// @param number   the number
//
// @return the object
//

- (DShort *) init :(short) number
{
  [self init];

  _sh = number;

  return self;
}



//// Main methods

//
// Get the short number
//
// @return the number
//

- (short) get
{
  return _sh;
}

//
// Set the short number
//
// @param number  the short
//
// @return the object
//

- (DShort *) set :(short) number
{
  _sh = number;

  return self;
}



//// Comparable protocol


//
// Compare two short objects
//
// @param other    the object to compare with
//
// @return the result of the comparison (-1,0,1)
//

- (int) compare :(DShort *) other
{
  if (self != other)
  {
    short i = [other get];
    
    if (_sh == i)
    {
      return 0;
    }
    else if (_sh > i)
    {
      return 1;
    }
    else
    {
      return -1;
    }
  }
  else
  {
    return 0;
  }
}
    
  
//// Parsable protocol

//
// Parse a string for a short number
//
// @param cstr     the c-string (moved to first non-parseable char)
//
// @return the result (0, ERANGE, ENODATA)
//

- (int) fromString :(char **) cstr
{
  int   result = 0;
  long  number = 0;
  char *src    = *cstr;
   
  number = strtol(*cstr, cstr, 0);

  if (src == *cstr)
  {
    result = ENODATA;
  }
  else if ((number < SHRT_MIN) || (number > SHRT_MAX))
  {
    result = ERANGE;
  }
  else
  {
    _sh = (short) number;
  }

  return result;
}


//// Textable protocol

//
// Return a text string 
//
// @return a (new) text string with the  number
//

- (DText *) toText
{
  return [[[DText alloc] init] format :"%d",_sh];
}
    

//// Datable protocol

//
// Return a data string
//
// @return a (new) data string
//

- (DData *) toData
{
  return [[DData alloc] init :(unsigned char *)&_sh :sizeof(_sh)];
}



//// Endian methods

//
// Convert the short to a Big Endian (network order) short
//
// @return the converted short
//

- (short) toBigEndian 
{
  short number = _sh;
  
#ifndef WORDS_BIGENDIAN 
  number = ((number >> 8) & 0x00ff) | ((number << 8) & 0xff00);
#endif

  return number;
}

//
// Convert the short to a Little Endian short
//
// @return the converted short
//

- (short) toLittleEndian 
{
  short number = _sh;
  
#ifdef WORDS_BIGENDIAN 
  number = ((number >> 8) & 0x00ff) | ((number << 8) & 0xff00);
#endif

  return number;
}

@end

/*==========================================================================*/

